package com.matrix.framework.core.listcrud;


import com.matrix.framework.core.common.global.Pager;
import com.matrix.framework.core.common.utils.Common;
import com.matrix.framework.core.listcrud.data.BaseData;
import com.matrix.framework.core.listcrud.service.IListCrudService;
import com.matrix.framework.core.listcrud.service.impl.ListCrudServiceImpl;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;

/**
 * List增删改查服务工厂类（多例模式）
 * 每个实例维护独立的数据存储，避免数据混淆
 *
 * Copyright © 海平面工作室 版权所有
 *
 * @Author: Leo
 * @Create: 2025/9/20 11:00
 * @Since 1.2
 */
public class ListCrudFactory {

    /**
     * 服务实例缓存，每个工厂实例维护独立的缓存
     */
    private final Map<Class<?>, IListCrudService<?>> serviceCache = new ConcurrentHashMap<>();

    /**
     * 构造函数，允许创建多个实例
     */
    public ListCrudFactory() {
    }

    // ================================
    // 静态工厂方法
    // ================================

    /**
     * 创建新的工厂实例
     * 
     * @return 新的工厂实例
     */
    public static ListCrudFactory create() {
        return new ListCrudFactory();
    }

    // ================================
    // 基础服务管理方法
    // ================================

    /**
     * 获取指定类型的List增删改查服务实例
     * 
     * @param clazz 数据类型Class
     * @param <T> 数据类型，必须继承BaseData
     * @return List增删改查服务实例
     */
    @SuppressWarnings("unchecked")
    public <T extends BaseData> IListCrudService<T> getService(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("数据类型不能为null");
        }
        
        return (IListCrudService<T>) serviceCache.computeIfAbsent(clazz, 
                k -> new ListCrudServiceImpl<>());
    }

    /**
     * 创建新的List增删改查服务实例（不使用缓存）
     * 
     * @param <T> 数据类型，必须继承BaseData
     * @return 新的List增删改查服务实例
     */
    public <T extends BaseData> IListCrudService<T> createNewService() {
        return new ListCrudServiceImpl<>();
    }

    /**
     * 清空指定类型的服务缓存
     * 
     * @param clazz 数据类型Class
     */
    public void clearCache(Class<?> clazz) {
        if (clazz != null) {
            serviceCache.remove(clazz);
        }
    }

    /**
     * 清空所有服务缓存
     */
    public void clearAllCache() {
        serviceCache.clear();
    }

    /**
     * 获取缓存的服务数量
     * 
     * @return 缓存的服务数量
     */
    public int getCacheSize() {
        return serviceCache.size();
    }

    // ================================
    // JSON导入导出方法
    // ================================

    /**
     * 从JSON字符串加载数据到指定类型的服务中
     * 
     * @param json JSON字符串，包含数据列表
     * @param clazz 数据类型Class
     * @param <T> 数据类型，必须继承BaseData
     * @return 加载成功的数据条数，失败返回0
     */
    public <T extends BaseData> int load(String json, Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("数据类型不能为null");
        }
        
        // 如果json为空,直接返回0
        if (json == null || json.trim().isEmpty()) {
            return 0;
        }
        
        try {
            // 使用Common工具类进行JSON反序列化
            List<T> dataList = Common.jsonToList(json, clazz);
            if (dataList == null || dataList.isEmpty()) {
                return 0;
            }
            
            // 获取服务实例并批量保存数据
            IListCrudService<T> service = getService(clazz);
            //service.load(dataList);
            List<T> savedData = service.saveAll(dataList);
            
            return savedData != null ? savedData.size() : 0;
        } catch (Exception e) {
            throw new RuntimeException("从JSON加载数据失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从JSON字符串加载数据到指定类型的服务中（清空现有数据）
     * 
     * @param json JSON字符串，包含数据列表
     * @param clazz 数据类型Class
     * @param clearExisting 是否清空现有数据
     * @param <T> 数据类型，必须继承BaseData
     * @return 加载成功的数据条数，失败返回0
     */
    public <T extends BaseData> int load(String json, Class<T> clazz, boolean clearExisting) {
        if (clearExisting) {
            // 清空现有数据
            IListCrudService<T> service = getService(clazz);
            service.deleteAll();
        }
        
        return load(json, clazz);
    }

    /**
     * 导出指定类型的所有数据为JSON字符串
     * 
     * @param clazz 数据类型Class
     * @param <T> 数据类型，必须继承BaseData
     * @return JSON字符串，如果没有数据返回"[]"
     */
    public <T extends BaseData> String export(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("数据类型不能为null");
        }
        
        try {
            IListCrudService<T> service = getService(clazz);
            List<T> dataList = service.findAll();
            
            // 使用Common工具类进行JSON序列化
            String jsonResult = Common.listToJson(dataList, clazz);
            return jsonResult != null ? jsonResult : "[]";
        } catch (Exception e) {
            throw new RuntimeException("导出数据为JSON失败: " + e.getMessage(), e);
        }
    }

    /**
     * 根据条件导出数据为JSON字符串
     * 
     * @param clazz 数据类型Class
     * @param condition 导出条件，为null时导出所有数据
     * @param <T> 数据类型，必须继承BaseData
     * @return JSON字符串，如果没有数据返回"[]"
     */
    public <T extends BaseData> String export(Class<T> clazz, Predicate<T> condition) {
        if (clazz == null) {
            throw new IllegalArgumentException("数据类型不能为null");
        }
        
        try {
            IListCrudService<T> service = getService(clazz);
            List<T> dataList = condition == null ? 
                    service.findAll() : 
                    service.findByCondition(condition);
            
            // 使用Common工具类进行JSON序列化
            String jsonResult = Common.listToJson(dataList, clazz);
            return jsonResult != null ? jsonResult : "[]";
        } catch (Exception e) {
            throw new RuntimeException("导出数据为JSON失败: " + e.getMessage(), e);
        }
    }

    /**
     * 导出指定ID列表的数据为JSON字符串
     * 
     * @param clazz 数据类型Class
     * @param ids ID列表
     * @param <T> 数据类型，必须继承BaseData
     * @return JSON字符串，如果没有数据返回"[]"
     */
    public <T extends BaseData> String exportByIds(Class<T> clazz, List<Long> ids) {
        if (clazz == null) {
            throw new IllegalArgumentException("数据类型不能为null");
        }
        if (ids == null || ids.isEmpty()) {
            return "[]";
        }
        
        return export(clazz, data -> ids.contains(data.getId()));
    }

    // ================================
    // 数据操作方法
    // ================================

    /**
     * 保存数据（新增或更新）
     * 
     * @param clazz 数据类型Class
     * @param entity 要保存的实体
     * @param <T> 数据类型，必须继承BaseData
     * @return 保存后的实体
     */
    public <T extends BaseData> T save(Class<T> clazz, T entity) {
        return getService(clazz).save(entity);
    }

    /**
     * 批量保存数据
     * 
     * @param clazz 数据类型Class
     * @param entities 要保存的实体列表
     * @param <T> 数据类型，必须继承BaseData
     * @return 保存后的实体列表
     */
    public <T extends BaseData> List<T> saveAll(Class<T> clazz, List<T> entities) {
        return getService(clazz).saveAll(entities);
    }

    /**
     * 根据ID删除数据
     * 
     * @param clazz 数据类型Class
     * @param id 要删除的数据ID
     * @param <T> 数据类型，必须继承BaseData
     * @return 是否删除成功
     */
    public <T extends BaseData> boolean deleteById(Class<T> clazz, Long id) {
        return getService(clazz).deleteById(id);
    }

    /**
     * 删除指定实体
     * 
     * @param clazz 数据类型Class
     * @param entity 要删除的实体
     * @param <T> 数据类型，必须继承BaseData
     * @return 是否删除成功
     */
    public <T extends BaseData> boolean delete(Class<T> clazz, T entity) {
        return getService(clazz).delete(entity);
    }

    /**
     * 批量删除
     * 
     * @param clazz 数据类型Class
     * @param ids 要删除的ID列表
     * @param <T> 数据类型，必须继承BaseData
     * @return 删除的数量
     */
    public <T extends BaseData> int deleteByIds(Class<T> clazz, List<Long> ids) {
        return getService(clazz).deleteByIds(ids);
    }

    /**
     * 删除所有满足条件的数据
     * 
     * @param clazz 数据类型Class
     * @param condition 删除条件
     * @param <T> 数据类型，必须继承BaseData
     * @return 删除的数量
     */
    public <T extends BaseData> int deleteByCondition(Class<T> clazz, Predicate<T> condition) {
        return getService(clazz).deleteByCondition(condition);
    }

    /**
     * 清空所有数据
     * 
     * @param clazz 数据类型Class
     * @param <T> 数据类型，必须继承BaseData
     */
    public <T extends BaseData> void deleteAll(Class<T> clazz) {
        getService(clazz).deleteAll();
    }

    /**
     * 根据ID查找数据
     * 
     * @param clazz 数据类型Class
     * @param id 数据ID
     * @param <T> 数据类型，必须继承BaseData
     * @return 查找到的数据，如果不存在则返回empty
     */
    public <T extends BaseData> Optional<T> findById(Class<T> clazz, Long id) {
        return getService(clazz).findById(id);
    }

    /**
     * 查找所有数据
     * 
     * @param clazz 数据类型Class
     * @param <T> 数据类型，必须继承BaseData
     * @return 所有数据列表
     */
    public <T extends BaseData> List<T> findAll(Class<T> clazz) {
        return getService(clazz).findAll();
    }

    /**
     * 根据条件查找数据
     * 
     * @param clazz 数据类型Class
     * @param condition 查询条件
     * @param <T> 数据类型，必须继承BaseData
     * @return 满足条件的数据列表
     */
    public <T extends BaseData> List<T> findByCondition(Class<T> clazz, Predicate<T> condition) {
        return getService(clazz).findByCondition(condition);
    }

    /**
     * 根据条件查找第一个数据
     * 
     * @param clazz 数据类型Class
     * @param condition 查询条件
     * @param <T> 数据类型，必须继承BaseData
     * @return 第一个满足条件的数据，如果不存在则返回empty
     */
    public <T extends BaseData> Optional<T> findFirstByCondition(Class<T> clazz, Predicate<T> condition) {
        return getService(clazz).findFirstByCondition(condition);
    }

    /**
     * 分页查询所有数据
     * 
     * @param clazz 数据类型Class
     * @param pager 分页参数对象
     * @param <T> 数据类型，必须继承BaseData
     * @return 分页结果
     */
    public <T extends BaseData> Pager<T> findAll(Class<T> clazz, Pager<T> pager) {
        return getService(clazz).findAll(pager);
    }

    /**
     * 分页条件查询
     * 
     * @param clazz 数据类型Class
     * @param condition 查询条件
     * @param pager 分页参数对象
     * @param <T> 数据类型，必须继承BaseData
     * @return 分页结果
     */
    public <T extends BaseData> Pager<T> findByCondition(Class<T> clazz, Predicate<T> condition, Pager<T> pager) {
        return getService(clazz).findByCondition(condition, pager);
    }

    /**
     * 统计总数
     * 
     * @param clazz 数据类型Class
     * @param <T> 数据类型，必须继承BaseData
     * @return 总记录数
     */
    public <T extends BaseData> long count(Class<T> clazz) {
        return getService(clazz).count();
    }

    /**
     * 统计满足条件的数据数量
     * 
     * @param clazz 数据类型Class
     * @param condition 查询条件
     * @param <T> 数据类型，必须继承BaseData
     * @return 满足条件的记录数
     */
    public <T extends BaseData> long countByCondition(Class<T> clazz, Predicate<T> condition) {
        return getService(clazz).countByCondition(condition);
    }

    /**
     * 判断是否存在指定ID的数据
     * 
     * @param clazz 数据类型Class
     * @param id 数据ID
     * @param <T> 数据类型，必须继承BaseData
     * @return 是否存在
     */
    public <T extends BaseData> boolean existsById(Class<T> clazz, Long id) {
        return getService(clazz).existsById(id);
    }

    /**
     * 判断是否存在满足条件的数据
     * 
     * @param clazz 数据类型Class
     * @param condition 查询条件
     * @param <T> 数据类型，必须继承BaseData
     * @return 是否存在
     */
    public <T extends BaseData> boolean existsByCondition(Class<T> clazz, Predicate<T> condition) {
        return getService(clazz).existsByCondition(condition);
    }
} 